﻿namespace DomainServices.Tools.SourceLocation
{
    using System;
    using System.Collections.Generic;
    using System.Reflection;

    internal class SourceInfo
    {
        private int _column;
        private string _fileName;
        private int _line;
        private static PropertyInfo columnProperty;
        private static PropertyInfo fileNameProperty;
        private static PropertyInfo lineProperty;
        private static Type sourceInfoAttributeType;
        private const string SourceInfoAttributeTypeName = "Microsoft.VisualStudio.ServiceModel.DomainServices.Intellisense.SourceInfoAttribute";

        private SourceInfo(string fileName, int line, int column)
        {
            this._fileName = fileName;
            this._line = line;
            this._column = column;
        }

        private static SourceInfo GetSourceInfoFromAttribute(object attribute)
        {
            if (sourceInfoAttributeType == null)
            {
                Type type = attribute.GetType();
                sourceInfoAttributeType = type;
                fileNameProperty = type.GetProperty("FileName", BindingFlags.Public | BindingFlags.Instance);
                if ((fileNameProperty != null) && (fileNameProperty.PropertyType != typeof(string)))
                {
                    fileNameProperty = null;
                }
                lineProperty = type.GetProperty("Line", BindingFlags.Public | BindingFlags.Instance);
                if ((lineProperty != null) && (lineProperty.PropertyType != typeof(int)))
                {
                    lineProperty = null;
                }
                columnProperty = type.GetProperty("Column", BindingFlags.Public | BindingFlags.Instance);
                if ((columnProperty != null) && (columnProperty.PropertyType != typeof(int)))
                {
                    columnProperty = null;
                }
            }
            if (((fileNameProperty == null) || (lineProperty == null)) || (columnProperty == null))
            {
                return null;
            }
            string fileName = (string) fileNameProperty.GetValue(attribute, null);
            int line = (int) lineProperty.GetValue(attribute, null);
            return new SourceInfo(fileName, line, (int) columnProperty.GetValue(attribute, null));
        }

        internal static SourceInfo GetSourceInfoFromAttributes(IEnumerable<object> attributes)
        {
            foreach (object obj2 in attributes)
            {
                Type type = obj2.GetType();
                if (((sourceInfoAttributeType != null) && (type == sourceInfoAttributeType)) || type.FullName.EndsWith("Microsoft.VisualStudio.ServiceModel.DomainServices.Intellisense.SourceInfoAttribute", StringComparison.Ordinal))
                {
                    return GetSourceInfoFromAttribute(obj2);
                }
            }
            return null;
        }

        internal int Column
        {
            get
            {
                return this._column;
            }
        }

        internal string FileName
        {
            get
            {
                return this._fileName;
            }
        }

        internal int Line
        {
            get
            {
                return this._line;
            }
        }
    }
}

